package com.axonactive.yolo.util;

import java.util.ArrayList;
import java.util.List;
import java.util.Iterator;
import java.util.List;

import org.apache.log4j.Logger;

import com.axonactive.yolo.dto.Airline;
import com.axonactive.yolo.dto.AirportArrival;
import com.axonactive.yolo.dto.AirportDeparture;
import com.axonactive.yolo.dto.Flight;
import com.axonactive.yolo.dto.InBound;
import com.axonactive.yolo.dto.OutBound;
import com.axonactive.yolo.dto.Price;
import com.axonactive.yolo.dtotemp.Carrier;
import com.axonactive.yolo.dtotemp.Location;
import com.axonactive.yolo.dtotemp.Schedule;
import com.axonactive.yolo.dtotemp.WegoFlight;

public class WegoUtilities {
	private static final Logger LOGGER = Logger.getLogger(WegoUtilities.class);
	/***
	 * Used for display information of wego flights to console
	 * 
	 * @param flights
	 */
	public static void Display(List<WegoFlight> flights) {
		// How many result
		LOGGER.info("Total result: " + flights.size());
		int size = (flights.size() > 10) ? flights.size() : flights.size();
		for (int i = 0; i < size; i++) {
			WegoFlight flight = flights.get(i);
			LOGGER.info("\n" + i
					+ ".--------------------------------------");
			LOGGER.info("Provider ID: " + flight.getProviderId());
			LOGGER.info("Origin CountryCode: "
					+ flight.getOriginCountryCode());
			LOGGER.info("Destination CountryCode: "
					+ flight.getDestinationCountryCode());
			LOGGER.info("Airlines (code-name): ");
			for (int j = 0; j < flight.getCarriers().size(); j++)
				LOGGER.info(flight.getCarriers().get(j).getCode() + "-"
						+ flight.getCarriers().get(j).getName() + ",");
			LOGGER.info("\nAirports (code - name): ");
			for (int j = 0; j < flight.getLocations().size(); j++)
				LOGGER.info(flight.getLocations().get(j).getCode() + "-"
						+ flight.getLocations().get(j).getName() + ",");
			LOGGER.info("\nPrice: " + flight.getPrice().getAmount()
					+ " " + flight.getPrice().getCurrencyCode());
			LOGGER.info("Departure Flight Information: ");
			LOGGER.info("\t Flight number: ");
			for (int j = 0; j < flight.getOutboundInfo().getFlightNumbers().length; j++)
				LOGGER.info(flight.getOutboundInfo().getFlightNumbers()[j]
						+ ",");
			LOGGER.info("\n\t Airports: ");
			for (int j = 0; j < flight.getOutboundInfo().getAirports().length; j++)
				LOGGER.info(flight.getOutboundInfo().getAirports()[j]
						+ ",");
			LOGGER.info("\n\t Local Departure time: "
					+ flight.getOutboundInfo().getLocalDepartureTimeStr());
			LOGGER.info("\t Local Arrival time: "
					+ flight.getOutboundInfo().getLocalArrivalTimeStr());
			LOGGER.info("\t Num stops: "
					+ flight.getOutboundInfo().getNumStops());
			LOGGER.info("\t Duration(min): "
					+ flight.getOutboundInfo().getDurationInMin());
			LOGGER.info("\t Flight classes: ");
			for (int j = 0; j < flight.getOutboundInfo().getFlightClasses()
					.size(); j++)
				LOGGER.info(flight.getOutboundInfo().getFlightClasses()
						.get(j).getName()
						+ ",");
			System.out
					.println("\nArrival Flight Information for round trip search: ");
			if (flight.getInboundInfo() != null) {
				LOGGER.info("\t Flight number: ");
				for (int j = 0; j < flight.getInboundInfo().getFlightNumbers().length; j++)
					System.out
							.print(flight.getInboundInfo().getFlightNumbers()[j]
									+ ",");
				LOGGER.info("\n\t Airports: ");
				for (int j = 0; j < flight.getInboundInfo().getAirports().length; j++)
					LOGGER.info(flight.getInboundInfo().getAirports()[j]
							+ ",");
				LOGGER.info("\n\t Local Departure time: "
						+ flight.getInboundInfo().getLocalDepartureTimeStr());
				LOGGER.info("\t Local Arrival time: "
						+ flight.getInboundInfo().getLocalArrivalTimeStr());
				LOGGER.info("\t Num stops: "
						+ flight.getInboundInfo().getNumStops());
				LOGGER.info("\t Duration(min): "
						+ flight.getInboundInfo().getDurationInMin());
				LOGGER.info("\t Flight classes: ");
				for (int j = 0; j < flight.getInboundInfo().getFlightClasses()
						.size(); j++)
					LOGGER.info(flight.getInboundInfo().getFlightClasses()
							.get(j).getName()
							+ ",");
			} else
				LOGGER.info("Not available for oneway option");
		}
	}

	public static String parseNumber(long number) {
		try {
			return String.valueOf(number);
		} catch (NumberFormatException ex) {
			LOGGER.error("WegoUtilities class parseNumber error",ex);
		}
		return "";
	}

	public static String getAirportNameFromCode(String code,
			WegoFlight wegoFlight) {
		List<Location> airports = wegoFlight.getLocations();
		for (Iterator iterator = airports.iterator(); iterator.hasNext();) {
			Location location = (Location) iterator.next();
			if (location.getCode().equals(code))
				return location.getName();
		}
		return "";
	}

	public static String getAirlineNameFromCode(String code,
			WegoFlight wegoFlight) {
		List<Carrier> airlines = wegoFlight.getCarriers();
		for (Iterator iterator = airlines.iterator(); iterator.hasNext();) {
			Carrier carrier = (Carrier) iterator.next();
			if (carrier.getCode().equals(code))
				return carrier.getName();
		}
		return "";
	}

	public static String getAirportsExpanded(WegoFlight wegoFlight,
			boolean isInOrOutBound) {
		Schedule schedule = (isInOrOutBound == true) ? wegoFlight
				.getInboundInfo() : wegoFlight.getOutboundInfo();
		if (schedule == null)
			return "";
		String strAirportExp = schedule.getAirportsExpanded()[0] + " - "
				+ schedule.getAirportsExpanded()[1];
		for (int i = 3; i < schedule.getAirportsExpanded().length; i += 2) {
			// if(schedule.getAirportsExpanded()[i])
			strAirportExp += " - " + schedule.getAirportsExpanded()[i];
		}
		return strAirportExp;
	}

	public static List<AirportDeparture> getDepartureAirports(
			WegoFlight wegoFlight, boolean isGetInBound) {
		List<AirportDeparture> lst = new ArrayList<AirportDeparture>();
		AirportDeparture airport = null;
		Airline airline = new Airline();
		Schedule schedule = (isGetInBound == true) ? wegoFlight
				.getInboundInfo() : wegoFlight.getOutboundInfo();
		if (schedule == null)
			return null;
		String[] airportExpanded = schedule.getAirportsExpanded();
		for (int i = 0, j = 0; i < airportExpanded.length; i += 2, j++) {
			airport = new AirportDeparture();
			airport.setCode(airportExpanded[i]);
			airport.setName(getAirportNameFromCode(airportExpanded[i],
					wegoFlight));
			// set airline
			String flightNumber = schedule.getFlightNumbers()[j];
			airline.setFlightClass(schedule.getFlightClasses().get(0).getName());
			airline.setFlightNumber(flightNumber);
			airline.setName(getAirlineNameFromCode(
					flightNumber.substring(0, 2), wegoFlight));
			//
			airport.setAirline(airline);
			// set departure time for the first departure airport.
			if (i == 0) {
				airport.setLocalDepartureTime(schedule.getLocalDepartureTimeStr());
				airport.setDepartureTime(parseNumber(schedule
						.getDepartureTime() / 1000));
			}
			lst.add(airport);
		}
		return lst;
	}

	public static List<AirportArrival> getArrivalAirports(
			WegoFlight wegoFlight, boolean isGetInBound) {
		List<AirportArrival> lst = new ArrayList<AirportArrival>();
		AirportArrival airport = null;
		Airline airline = new Airline();
		Schedule schedule = (isGetInBound == true) ? wegoFlight
				.getInboundInfo() : wegoFlight.getOutboundInfo();
		if (schedule == null)
			return null;
		String[] airportExpanded = schedule.getAirportsExpanded();
		for (int i = 1, j = 0; i < airportExpanded.length; i += 2, j++) {
			airport = new AirportArrival();
			airport.setCode(airportExpanded[i]);
			airport.setName(getAirportNameFromCode(airportExpanded[i],
					wegoFlight));
			// set airline
			String flightNumber = schedule.getFlightNumbers()[j];
			airline.setFlightClass(schedule.getFlightClasses().get(0).getName());
			airline.setFlightNumber(flightNumber);
			airline.setName(getAirlineNameFromCode(
					flightNumber.substring(0, 2), wegoFlight));
			//
			airport.setAirline(airline);
			// set departure time for the first departure airport.
			if (i == airportExpanded.length - 1)
			{
				airport.setLocalArrivalTime(schedule.getLocalArrivalTimeStr());
				airport.setArrivalTime(parseNumber(schedule.getArrivalTime() / 1000));
			}
			lst.add(airport);
		}
		return lst;
	}

	public static Flight convertToFlight(WegoFlight wegoFlight) {

		Flight flight = new Flight();
		// copy price
		Price price = new Price();
		price.setAmount(wegoFlight.getPrice().getAmount());
		price.setCurrencyCode(wegoFlight.getPrice().getCurrencyCode());
		flight.setPrice(price);
		// copy inbound information
		flight.setInBound(getInBound(wegoFlight));
		// copy outbound information
		flight.setOutBound(getOutBound(wegoFlight));
		return flight;
	}

	public static OutBound getOutBound(WegoFlight wegoFlight) {
		OutBound out = new OutBound();
		// + airportsExpanded
		out.setAirportsExpanded(getAirportsExpanded(wegoFlight, false));
		// + departure and arrival airports
		List<AirportDeparture> departAirports = getDepartureAirports(
				wegoFlight, false);
		List<AirportArrival> arriveAirports = getArrivalAirports(
				wegoFlight, false);
		out.setDepartAirports(departAirports);
		out.setArriveAirports(arriveAirports);
		// + copy number of stops
		out.setNumberStops(parseNumber(wegoFlight.getOutboundInfo()
				.getNumStops()));
		// + copy duration in minute
		out.setTotalDuration(parseNumber(wegoFlight.getOutboundInfo()
				.getDurationInMin()));
		return out;
	}

	public static InBound getInBound(WegoFlight wegoFlight) {
		if (wegoFlight.getInboundInfo() == null)
			return null;
		InBound in = new InBound();
		// + airportsExpanded
		in.setAirportsExpanded(getAirportsExpanded(wegoFlight, true));
		// + departure and arrival airports
		List<AirportDeparture> departAirports = getDepartureAirports(
				wegoFlight, true);
		List<AirportArrival> arriveAirports = getArrivalAirports(
				wegoFlight, true);
		in.setDepartAirports(departAirports);
		in.setArriveAirports(arriveAirports);
		// + copy number of stops
		in.setNumberStops(parseNumber(wegoFlight.getInboundInfo().getNumStops()));
		// + copy duration in minute
		in.setTotalDuration(parseNumber(wegoFlight.getInboundInfo()
				.getDurationInMin()));
		return in;
	}


	/***
	 * Used for display information of flight object
	 * (com.axonactive.yolo.domain.Flight) to console
	 */
//	public static void displayFlight(Flight flight) {
//
//		LOGGER.info("Amount: " + flight.getPrice().getAmount());
//		LOGGER.info("Currency Code: "
//				+ flight.getPrice().getCurrencyCode());
//		// ----------------------Outbound information
//		displayOutBound(flight);
//		// ----------------------Inbound information
//		displayInBound(flight);
//	}

//	private static void displayInBound(Flight flight) {
//		if (flight.getInBound() == null)
//			return;
//		Utils util = new Utils();
//		LOGGER.info("___Inbound Information_____");
//		LOGGER.info("Number of stops: "
//				+ flight.getInBound().getNumberStops());
//		LOGGER.info("Duration: "
//				+ flight.getInBound().getTotalDuration());
//		LOGGER.info("Departure Airports:");
//		List<AirportDeparture> airportDepartures = flight.getInBound()
//				.getDepartAirports();
//		for (Iterator iterator = airportDepartures.iterator(); iterator
//				.hasNext();) {
//			AirportDeparture airportDeparture = (AirportDeparture) iterator
//					.next();
//			LOGGER.info("\tCode: " + airportDeparture.getCode());
//			LOGGER.info("\tName: " + airportDeparture.getName());
//			airportDeparture.setDepartureTime(Utils.convertUnixTimeToDateTime(
//					airportDeparture.getDepartureTime(),
//					CONSTANTS.DATE_TIME_FORMAT));
//			LOGGER.info("\tDepartureTime: "
//					+ airportDeparture.getDepartureTime());
//			LOGGER.info("\tFlight Class: "
//					+ airportDeparture.getAirline().getFlightClass());
//			LOGGER.info("\tFlight Number: "
//					+ airportDeparture.getAirline().getFlightNumber());
//			LOGGER.info("\tName of Carrier: "
//					+ airportDeparture.getAirline().getName());
//			LOGGER.info("\t---------------");
//		}
//		LOGGER.info("Arrival Airports:");
//		List<AirportArrival> airportArrivals = flight.getInBound()
//				.getArriveAirports();
//		for (Iterator iterator = airportArrivals.iterator(); iterator.hasNext();) {
//			AirportArrival airportArrival = (AirportArrival) iterator.next();
//			LOGGER.info("\tCode: " + airportArrival.getCode());
//			LOGGER.info("\tName: " + airportArrival.getName());
//			airportArrival
//					.setArrivalTime(Utils.convertUnixTimeToDateTime(
//							airportArrival.getArrivalTime(),
//							CONSTANTS.DATE_TIME_FORMAT));
//			LOGGER.info("\tArrivalTime: "
//					+ airportArrival.getArrivalTime());
//			LOGGER.info("\tFlight Class: "
//					+ airportArrival.getAirline().getFlightClass());
//			LOGGER.info("\tFlight Number: "
//					+ airportArrival.getAirline().getFlightNumber());
//			LOGGER.info("\tName of Carrier: "
//					+ airportArrival.getAirline().getName());
//			LOGGER.info("\t---------------");
//		}
//
//	}
//
//	private static void displayOutBound(Flight flight) {
//		Utils util = new Utils();
//		LOGGER.info("___Outbound Information_____");
//		LOGGER.info("Number of stops: "
//				+ flight.getOutBound().getNumberStops());
//		LOGGER.info("Duration: "
//				+ flight.getOutBound().getTotalDuration());
//		LOGGER.info("Departure Airports:");
//		List<AirportDeparture> airportDepartures = flight.getOutBound()
//				.getDepartAirports();
//		for (Iterator iterator = airportDepartures.iterator(); iterator
//				.hasNext();) {
//			AirportDeparture airportDeparture = (AirportDeparture) iterator
//					.next();
//			LOGGER.info("\tCode: " + airportDeparture.getCode());
//			LOGGER.info("\tName: " + airportDeparture.getName());
//			airportDeparture.setDepartureTime(Utils.convertUnixTimeToDateTime(
//					airportDeparture.getDepartureTime(),
//					CONSTANTS.DATE_TIME_FORMAT));
//			LOGGER.info("\tDepartureTime: "
//					+ airportDeparture.getDepartureTime());
//			LOGGER.info("\tFlight Class: "
//					+ airportDeparture.getAirline().getFlightClass());
//			LOGGER.info("\tFlight Number: "
//					+ airportDeparture.getAirline().getFlightNumber());
//			LOGGER.info("\tName of Carrier: "
//					+ airportDeparture.getAirline().getName());
//			LOGGER.info("\t---------------");
//		}
//		LOGGER.info("Arrival Airports:");
//		List<AirportArrival> airportArrivals = flight.getOutBound()
//				.getArriveAirports();
//		for (Iterator iterator = airportArrivals.iterator(); iterator.hasNext();) {
//			AirportArrival airportArrival = (AirportArrival) iterator.next();
//			LOGGER.info("\tCode: " + airportArrival.getCode());
//			LOGGER.info("\tName: " + airportArrival.getName());
//			airportArrival
//					.setArrivalTime(Utils.convertUnixTimeToDateTime(
//							airportArrival.getArrivalTime(),
//							CONSTANTS.DATE_TIME_FORMAT));
//			LOGGER.info("\tArrivalTime: "
//					+ airportArrival.getArrivalTime());
//			LOGGER.info("\tFlight Class: "
//					+ airportArrival.getAirline().getFlightClass());
//			LOGGER.info("\tFlight Number: "
//					+ airportArrival.getAirline().getFlightNumber());
//			LOGGER.info("\tName of Carrier: "
//					+ airportArrival.getAirline().getName());
//			LOGGER.info("\t---------------");
//		}
//	}
}
